#pragma once

#ifndef LHJ_CORE_DEVICE_SERIAL_H__
#define LHJ_CORE_DEVICE_SERIAL_H__

#include <thread>
#include <mutex>
#include <string>
#include <map>

namespace cores
{
    namespace devices
    {
        class SerialPort
        {
        private:
            int fd = -1;
            // 连接状态
            int ConnStatus = -1;
            // 后台接收线程
            std::thread tid;
            // 对字符流加的锁
            std::mutex mutex;

            std::string _portName;
            int _baud_rate;
            int _data_bit;

            void open_port();
            void close_port();
            // 将数字型波特率转化为系统调用参数
            int transformBaud(const int &baudrate);
            // 将数字型数据位数转化为系统调用参数
            int transformDataBits(const int &dataBits);

            static std::map<int, int> gBaudRateMap;

            static std::map<int, int> gDatabitsMap;

        public:
            // 无校验
            static const int PARITY_NONE = 0;
            // 奇校验
            static const int PARITY_ODD = 1;
            // 偶校验
            static const int PARITY_EVEN = 2;
            // 函数成功
            static const int OK = 1;
            // 设备未找到
            static const int DEV_NOT_FOUND = -1;
            // 不支持该波特率
            static const int BAUD_NOT_SUPPORTED = -2;
            // 不支持该数据位数
            static const int DATABITS_NOT_SUPPORTED = -3;
            // 不支持该校验模式
            static const int PARITYMODE_NOT_SUPPORTED = -4;
            // 不支持该停止位数
            static const int STOPBITS_NOT_SUPPORTED = -5;
            // 未知配置错误
            static const int CONFIG_FAIL = -6;
            // 创建线程出错
            static const int NEW_THREAD_FAIL = -7;
            // 成功读到结尾符
            static const int READ_END = 1;
            // 读取超时
            static const int READ_TIMEOUT = -1;
            // 读取时缓冲区满
            static const int READ_BUFFER_FULL = -2;

            SerialPort(const std::string& dev_name, const int &baudRate = 9600, const int &dataBits = 8);
            ~SerialPort();

            bool isOpen() const;

            int readData(char *buffer, const size_t& size);
            int readData(unsigned char *buffer, const size_t& size);

            int writeData(const char *buffer, const size_t& size);

            int writeData(const unsigned char *buffer, const size_t& size);
        };
    }
}

#endif